/*
 *  Copyright (C) 2010 Matthias Buch-Kromann <mbk.isv@cbs.dk>
 * 
 *  This file is part of the IncrementalParser package.
 *  
 *  The IncrementalParser program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 * 
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.osdtsystem.incparser.featureextraction;

import gnu.trove.TIntHashSet;
import java.util.ArrayList;
import java.util.List;
import org.osdtsystem.incparser.featureextraction.intlist.IntList;
import org.osdtsystem.incparser.featureextraction.intlist.IntListFactory;
import org.osdtsystem.incparser.features.FeatureHandler;
import org.osdtsystem.incparser.graphs.FeatureExtractorOutdateListener;
import org.osdtsystem.incparser.graphs.Graph;

/**
 *
 * @author Matthias Buch-Kromann <mbk.isv@cbs.dk>
 */
public abstract class AbstractFeatureExtractor implements FeatureExtractor {
    final TIntHashSet intFeatureSet = new TIntHashSet();
    final TIntHashSet objectFeatureSet = new TIntHashSet();
    final FeatureHandler featureHandler;
    final List<FeatureExtractorOutdateListener> outdateListeners = new ArrayList<FeatureExtractorOutdateListener>();

    // Global feature group counter
    static int nextFeatureGroup = 0;
    static final List<String> featureGroups = new ArrayList<String>();

    public AbstractFeatureExtractor(FeatureHandler featureHandler) {
        this.featureHandler = featureHandler;
    }

    public void addOutdateListener(FeatureExtractorOutdateListener listener) {
        outdateListeners.add(listener);
    }

    void registerIntFeatures(int... features) {
        intFeatureSet.addAll(features);
    }

    void registerObjectFeatures(int... features) {
        objectFeatureSet.addAll(features);
    }
    
    public boolean isRegisteredIntFeature(int feature) {
        return intFeatureSet.contains(feature);
    }

    public boolean isRegisteredObjectFeature(int feature) {
        return objectFeatureSet.contains(feature);
    }

    public void outdate(Graph graph, int node) {
        for (FeatureExtractorOutdateListener outdateListener : outdateListeners)
            outdateListener.outdate(graph, node);
    }

    public static int reserveFeatureGroups(int count, String name) {
        int first = nextFeatureGroup;
        for (int i = 0; i < count; ++i)
            featureGroups.add(name + "$" + i);
        nextFeatureGroup += count;
        return first;
    }
    
    // Feature combiners
    final static IntList combine(int group, int f1) {
        return IntListFactory.combine(group, f1);
    }

    final static IntList combine(int group, int f1, int f2) {
        return IntListFactory.combine(group, f1, f2);
    }

    final static IntList combine(int group, int f1, int f2, int f3) {
        return IntListFactory.combine(group, f1, f2, f3);
    }

    final static IntList combine(int group, int f1, int f2, int f3, int f4) {
        return IntListFactory.combine(group, f1, f2, f3, f4);
    }

    final static IntList combine(int group, int f1, int f2, int f3, int f4, int f5) {
        return IntListFactory.combine(group, f1, f2, f3, f4, f5);
    }

    final static IntList combine(int group, int f1, int f2, int f3, int f4, int f5, int f6) {
        return IntListFactory.combine(group, f1, f2, f3, f4, f5, f6);
    }

    final static IntList combine(int group, int f1, int f2, int f3, int f4, int f5, int f6, int f7) {
        return IntListFactory.combine(group, f1, f2, f3, f4, f5, f6, f7);
    }

    final static IntList combine(int group, int f1, int f2, int f3, int f4, int f5, int f6, int f7, int f8) {
        return IntListFactory.combine(group, f1, f2, f3, f4, f5, f6, f7, f8);
    }
}

